import config from '@/config/index'
import * as mqtt from 'mqtt/dist/mqtt.min'

const serverUrl = process.env.NODE_ENV === 'development' ? config.mqttUrl.dev : config.mqttUrl.pro
const showToast = function (title, time, icon = 'none') {
	console.log(title)
}
let client
let options = {
  wsOptions: {},
  protocolVersion: 4, // MQTT连接协议版本
  clientId: Math.ceil(Math.random() * 1000000),
  keepalive: 60,
  clean: false,
  reconnectPeriod: 1000, // 1000毫秒，两次重新连接之间的间隔
  connectTimeout: 30 * 1000, // 1000毫秒，两次重新连接之间的间隔
  resubscribe: true // 如果连接断开并重新连接，则会再次自动订阅已订阅的主题（默认true）
}

class MQTT {
	// In Vue 3, Vue is not a constructor anymore, and Vue.createApp({}); 
	// returns an object that has no $on and $emit methods.
	// So, implement event bus.
	constructor(){
		this.events = {};
	}

	$on(eventName, fn) {
		this.events[eventName] = this.events[eventName] || [];
		this.events[eventName].push(fn);
	}

	$off(eventName, fn) {
		if (this.events[eventName]) {
			for (var i = 0; i < this.events[eventName].length; i++) {
				if (this.events[eventName][i] === fn) {
					this.events[eventName].splice(i, 1);
					break;
				}
			};
		}
	}

	$emit(eventName, data) {
		if (this.events[eventName]) {
			this.events[eventName].forEach(function(fn) {
					fn(data);
			});
		}
	}

	publish (topic, msg) {
		// 判断是否已成功连接
		if (!client || !client.connected) {
			showToast('客户端未连接', 1000)
			return
		}
		if (msg && msg != '') {
			client.publish(topic, msg, error => {
				console.log(error || '消息发布成功')
			})
		} else {
			showToast('发布消息为空', 1000)
		}
	}

	connect () {
		var ishttps = 'https:' == document.location.protocol ? true : false
		if (ishttps) {
			var hosts = 'wss://' + serverUrl
			console.log(ishttps)
		} else {
			console.log(ishttps)
			var hosts = 'ws://' + serverUrl
		}			
		if (client == null || client.connented === false) {
			console.log(hosts, options)
			client = mqtt.connect(
				hosts,
				options
			)
	
			client.on('connect', () => {
				showToast('连接成功', 1000, 'success')
				this.$emit('mqtt-connect')
			})
			client.on('message', (topic, message) => {
				console.log('收到来自' + topic + '的消息' + message.toString())
				this.$emit('mqtt-msg', { topic: topic, msg: message })
			})
		}
	
		client.on('reconnect', () => {
			showToast('正在重连···', 1000)
			this.$emit('mqtt-reconnect')
		})
	
		client.on('error', () => {
			showToast('连接失败!', 1000)
			this.$emit('mqtt-error')
		})
	}

	/**
	 * 订阅主题
	 * @param {Object} topic topic, topic Array, topic Array-Onject
	 * @param {Object} qos
	 */
	subscribe (topic, qos) {
		// 判断是否已成功连接
		if (!client || !client.connected) {
			showToast('客户端未连接', 1000)
			return
		}
	
		client.subscribe(topic, {
			qos: qos
		}, error => {
			if (!error) {
				// showToast('订阅成功', 1000, 'success')
				console.log('订阅成功' + topic)
			}
		})
	}

	/**
	 * 取消订阅
	 * @param {Object} onTopic topic, topic Array, topic Array-Onject
	 */
	unsubscribe (onTopic) {
		client.unsubscribe(
			onTopic,
			err => {
				console.log(err || '取消订阅成功')
				showToast('取消订阅成功', 1000, 'success')
			}
		)
	}

	/**
	 * 断开连接
	 */
	unconnect () {
		client.end()
		client = null
		showToast('成功断开连接', 1000, 'success')
		console.log('断开连接')
	}
}
const mqttInstance = new MQTT()
mqttInstance.connect()

export default mqttInstance